package org.example.mallchat.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import org.example.mallchat.common.constant.RedisKey;
import org.example.mallchat.common.utils.JwtUtils;
import org.example.mallchat.common.utils.RedisUtils;
import org.example.mallchat.service.LoginService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author: zzh
 * @date: 2024/12/20 11:22:48
 * @version: 1.0
 * @desc: 登录实现类
 */
@Service
public class LoginServiceImpl implements LoginService {

    private static final long TOKEN_EXPIRE_DAYS = 5;
    private static final long TOKEN_RENEWAL_DAYS = 1;

    @Resource
    private JwtUtils jwtUtils;

    /**
     * 刷新token
     * 采用异步的 ，Spring管理的线程池，这个时候管理线程池！
     * @param token
     */
    @Async
    @Override
    public void renewalTokenIfNecessary(String token) {
        // 验证token 解密出来
        Long uidOrNull = jwtUtils.getUidOrNull(token);
        if (ObjectUtil.isNull(uidOrNull)){
            return;
        }
        String key = RedisKey.generateKey(RedisKey.USER_TOKEN_STRING, uidOrNull);
        Long expire = RedisUtils.getExpire(key, TimeUnit.DAYS);// 获取时间，判断是否过期
        if (expire == -2){// key不存在的
            return;
        }
        if (expire < TOKEN_RENEWAL_DAYS){
            // 过期了,续期
            RedisUtils.expire(key, TOKEN_EXPIRE_DAYS, TimeUnit.DAYS);
        }
    }

    /**
     * 登录 并且生成token
     * @param uid
     * @return
     */
    @Override
    public String login(Long uid) {
        // 看看Redis是否有token
        // 有的话，说明之前登录过，直接返回token
        String key = RedisKey.generateKey(RedisKey.USER_TOKEN_STRING, uid);
        String token = RedisUtils.getStr(key);
        if (StrUtil.isNotBlank(token)){
            return token;    // 之前登录过，直接返回token
        }
        // 没有的话，说明之前没有登录过，生成token 根据uid 生成token
        token = jwtUtils.createToken(uid);
        //保存token到redis
        RedisUtils.set(key,token,TOKEN_EXPIRE_DAYS, TimeUnit.DAYS);
        return token;
    }

    /**
     * 获取有效的uid
     * @param token
     * @return
     */
    @Override
    public Long getValidUid(String token) {
        // 验证token 解密出来
        Long uid = jwtUtils.getUidOrNull(token);
        if (ObjectUtil.isNull(uid)){
            return null;
        }
        // 验证token是否有效 判断是否和redis中的token一致
        String key = RedisKey.generateKey(RedisKey.USER_TOKEN_STRING, uid);
        String redisToken = RedisUtils.getStr(key);
        if (StrUtil.equals(redisToken,token)){
            return uid;
        }
        return null;
    }
}
